package cd.zhixuan.utils.dialog;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;

import java.util.HashSet;
import java.util.Set;

import cd.zhixuan.utils.LogTools;

/**
 * @author: HuZC
 * @Description: 自定义Dialog弹框
 * @Date: 2022/1/7
 */
public abstract class IDialog extends Dialog {
    @NonNull
    protected final LayoutInflater mLayoutInflater;
    @NonNull
    public final Context mContext;
    @Nullable
    public final View rootView;
    @NonNull
    protected final Rect windowRect = new Rect();
    protected final Handler mHandler;
    private final Set<OnIDialogListener> onIDialogListeners = new HashSet<>(4);

    public IDialog(@NonNull Context context) {
        super(context);
        mContext = context;
        mHandler = new Handler();
        mLayoutInflater = LayoutInflater.from(context);
        //初始化builder
        final AlertDialog.Builder dialogBuilder;
        final int styleRes = styleRes();
        if (styleRes == 0) {
            dialogBuilder = new AlertDialog.Builder(context);
        } else {
            dialogBuilder = new AlertDialog.Builder(context, styleRes);
        }
//        //创建AlertDialog
//        alertDialog = dialogBuilder.create();
        //初始化window参数
        loadWindowParams();

        View view = layoutView();
        if (view == null) {
            final int layoutRes = layoutRes();
            if (layoutRes != 0) {
                view = mLayoutInflater.inflate(layoutRes, null, false);
            }
        }
        rootView = view;
        if (rootView != null) {
            initView();//初始化view
        } else {
            LogTools.w("root view is null !!!");
        }
        setContentView(rootView);
//        alertDialog.setView(rootView);
        super.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                for (DialogInterface.OnDismissListener listener : onIDialogListeners) {
                    listener.onDismiss(dialog);
                }
            }
        });
        super.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                for (DialogInterface.OnCancelListener listener : onIDialogListeners) {
                    listener.onCancel(dialog);
                }
            }
        });
        super.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {
                reinstallWindowParams();

                for (DialogInterface.OnShowListener listener : onIDialogListeners) {
                    listener.onShow(dialog);
                }
            }
        });
        super.setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                boolean onKey = false;
                for (DialogInterface.OnKeyListener listener : onIDialogListeners) {
                    if (listener.onKey(dialog, keyCode, event)) {
                        onKey = true;
                    }
                }
                return onKey;
            }
        });
    }

    /**
     * 加载window相关参数
     */
    private void loadWindowParams() {
        final Window window = getWindow();
        if (window == null) {
            return;
        }
        if (mContext instanceof Activity) {
            //当Activity为全屏时，设置window为全屏，否则可能会出现状态栏
            final WindowManager.LayoutParams attributes = ((Activity) mContext).getWindow().getAttributes();
            if ((attributes.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == WindowManager.LayoutParams.FLAG_FULLSCREEN) {
                window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            }
        }
        final WindowManager windowManager = window.getWindowManager();
        if (windowManager != null) {
            //获取window屏幕区域
            final Point point = new Point();
            windowManager.getDefaultDisplay().getSize(point);
//            final WindowMetrics currentWindowMetrics = windowManager.getCurrentWindowMetrics();
//            final Rect bounds = currentWindowMetrics.getBounds();
            windowRect.set(0, 0, point.x, point.y);
        }
        final WindowManager.LayoutParams lp = window.getAttributes();
        if (windowManager != null && lp != null) {
            initWindowParams(window, lp, windowManager);
        }
    }

    /**
     * 每次弹出dialog后才设置window参数
     */
    private void reinstallWindowParams() {
        final Window window = getWindow();
        if (window == null) {
            return;
        }
        final WindowManager wm = window.getWindowManager();
        if (wm == null) {
            return;
        }
        final WindowManager.LayoutParams lp = window.getAttributes();
        if (lp == null) {
            return;
        }
        afterShowed(window, lp, wm);
        window.setAttributes(lp);
    }

    /**
     * 显示弹框
     */
    public void show() {
        showDialogRunnable.run();
    }

    /**
     * 保证在主线程显示
     */
    public void showOnUiThread() {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            showDialogRunnable.run();
            return;
        }
        mHandler.post(showDialogRunnable);
    }

    private final Runnable showDialogRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                Window window = getWindow();
                if (window != null) {
                    WindowManager windowManager = window.getWindowManager();
                    WindowManager.LayoutParams lp = window.getAttributes();
                    if (lp != null && windowManager != null) {
                        beforeShow(window, lp, windowManager);
                    }
                }
                IDialog.super.show();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    @Override
    public void dismiss() {
        try {
            super.dismiss();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //    /**
//     * 关闭弹框
//     */
//    public void dissmiss() {
//        dismiss();
//    }

    /**
     * 通过id查找子view
     *
     * @param id  view id
     * @param <T> 返回view类型
     * @return 返回view
     */
    public final <T extends View> T findViewById(@IdRes int id) {
        if (rootView == null) return null;
        return rootView.findViewById(id);
    }

    /**
     * 关闭、销毁。如：在{@link Activity#onDestroy()}时调用
     */
    public void destroy() {
        mHandler.removeCallbacks(showDialogRunnable);
        dismiss();
    }


    /**
     * 添加监听
     */
    public final boolean addOnIDialogListener(OnIDialogListener listener) {
        if (listener == null) return false;
        try {
            return onIDialogListeners.add(listener);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public final boolean removeOnIDialogListener(OnIDialogListener listener) {
        if (listener == null) return false;
        try {
            return onIDialogListeners.remove(listener);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    //------------------------------------------------------------------------------------------
    //--------------------------- 屏蔽本身的监听设置 --------------------------------------------
    //------------------------------------------------------------------------------------------

    @Override
    @Deprecated
    public void setOnShowListener(@Nullable OnShowListener listener) {
    }

    @Override
    @Deprecated
    public void setOnDismissListener(@Nullable OnDismissListener listener) {
    }

    @Override
    @Deprecated
    public void setOnKeyListener(@Nullable OnKeyListener onKeyListener) {
    }

    @Override
    @Deprecated
    public void setOnCancelListener(@Nullable OnCancelListener listener) {
    }
    //------------------------------------------------------------------------------------------
    //--------------------------- interface -----------------------------------------------------
    //------------------------------------------------------------------------------------------

    /**
     * Dialog监听Listener
     */
    public interface OnIDialogListener extends DialogInterface.OnShowListener,
            DialogInterface.OnDismissListener, DialogInterface.OnCancelListener,
            DialogInterface.OnKeyListener {
    }

    //------------------------------------------------------------------------------------------
    //--------------------------- abstract -----------------------------------------------------
    //------------------------------------------------------------------------------------------

    /**
     * @return 风格res
     */
    @StyleRes
    public int styleRes() {
        //主要是noActionBar属性，若没有这个属性，设置dialog位置为top时会留出actionbar的距离
        return android.R.style.Theme_Holo_Dialog_NoActionBar;
    }

    /**
     * @return 根布局View，为Null时再加载{@link IDialog#layoutRes()}
     */
    @Nullable
    public abstract View layoutView();

    /**
     * @return 根布局layout
     */
    @LayoutRes
    public abstract int layoutRes();

    /**
     * 初始化view
     */
    public abstract void initView();

    /**
     * 初始化 window及相关参数，仅执行一次
     *
     * @param window Window
     * @param lp     WindowManager.LayoutParams
     */
    protected void initWindowParams(@NonNull Window window, @NonNull WindowManager.LayoutParams lp, @NonNull WindowManager wm) {
        window.requestFeature(Window.FEATURE_NO_TITLE);
        window.setBackgroundDrawableResource(android.R.color.transparent);
    }

    /**
     * 每次弹框前，设置window及相关参数
     *
     * @param window Window
     * @param lp     WindowManager.LayoutParams
     */
    protected void beforeShow(@NonNull Window window, @NonNull WindowManager.LayoutParams lp, @NonNull WindowManager wm) {
        LogTools.i("windowRect : " + windowRect.toString());
        if (mContext instanceof Activity) {
            window.setType(WindowManager.LayoutParams.TYPE_APPLICATION);
        } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
            window.setType(WindowManager.LayoutParams.TYPE_PHONE);
        } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) {
            window.setType(WindowManager.LayoutParams.TYPE_TOAST);
        } else {
            window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
        }
    }

    /**
     * 每次弹框后，设置window及相关参数
     *
     * @param window Window
     * @param lp     WindowManager.LayoutParams
     */
    protected void afterShowed(@NonNull Window window, @NonNull WindowManager.LayoutParams lp, @NonNull WindowManager wm) {
    }


}
